package cn.mesmile.image.compression;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.StrUtil;
import net.coobird.thumbnailator.Thumbnails;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author zb
 * @date 2021/3/9 17:03
 * @Description
 */
public class CompressionUtil {

    /*
        【关键api】
        //按指定大小把图片进行缩和放（会遵循原图高宽比例）  此处把图片压成400×500的缩略图
        Thumbnails.of(fromPic).size(400,500).toFile(toPic);//变为400*300,遵循原图比例缩或放到400*某个高度

        //按照比例进行缩小和放大
        Thumbnails.of(fromPic).scale(0.2f).toFile(toPic);//按比例缩小
        Thumbnails.of(fromPic).scale(2f);//按比例放大

        //图片尺寸不变，压缩图片文件大小outputQuality实现,参数1为最高质量
        Thumbnails.of(fromPic).scale(1f).outputQuality(0.25f).toFile(toPic);

        //给图片加水印，watermark(位置，水印图，透明度)Positions.CENTER表示加在中间
		Thumbnails.of(fromPic).size(400,400)
		.watermark(Positions.CENTER,ImageIO.read(waterPic),0.5f)
		.outputQuality(0.8f).toFile(toPic);

     */

    public static void main(String[] args) throws IOException {

        CompressionUtil.commpressPicForSize("C:\\Users\\Bing.Zheng1\\Desktop\\images\\src\\1h00208.JPG",
        "C:\\Users\\Bing.Zheng1\\Desktop\\images\\1h00208.JPG", 1024, 0.5);

        if(true){
            return;
        }

        double [] arr = {0.3,0.5};
        List<Double> ts = Convert.toList(Double.class,arr);
        ts.parallelStream().forEach(number-> {
            System.out.println("---------------------------------------------");
            TimeInterval timer = DateUtil.timer();
            String dest = "C:\\Users\\Bing.Zheng1\\Desktop\\images\\1h00208.JPG";
            File fromPic = new File("C:\\Users\\Bing.Zheng1\\Desktop\\images\\src\\1h00208.JPG");
            File toPic = new File(dest);
            //
//            Thumbnails.of(fromPic).scale(1f).outputQuality(arr[i]).toFile(toPic);

            try {
                Thumbnails.of(fromPic).scale(number).outputQuality(1F).toFile(toPic);
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 图片小于100kb
//        CompressionUtil.commpressPicForSize("C:\\Users\\Bing.Zheng1\\Desktop\\images\\src\\06A2800.JPG",
//                "C:\\Users\\Bing.Zheng1\\Desktop\\images\\06A2800.JPG", 1024, 0.8);

            //花费毫秒数
            long interval = timer.interval();
            //花费分钟数
            long minute = timer.intervalMinute();
            System.out.println("interval = " + interval);
            System.out.println("minute = " + minute);
            File desFile = new File(dest);
            System.out.println("目标图片：" + dest + "，大小" + desFile.length()
                    / 1024 + "kb");

            timer.intervalRestart();//返回花费时间，并重置开始时间
            System.out.println("---------------------------------------------");
        });

    }

    ///////////////////////////////////根据【指定大小】和【指定精度】压缩图片////////////////////////////////////////////

    /**
     * 根据【指定大小】和【指定精度】压缩图片
     *
     * @param srcPath 源图片地址
     * @param desPath 目标图片地址
     * @param desFileSize 指定图片大小，单位kb
     * @param accuracy 精度，递归压缩的比率，建议小于0.9
     * @return
     */
    public static String commpressPicForSize(String srcPath, String desPath,
                                             long desFileSize, double accuracy) {
        if (StrUtil.isEmpty(srcPath) || StrUtil.isEmpty(srcPath)) {
            return null;
        }
        if (!new File(srcPath).exists()) {
            return null;
        }
        try {
            File srcFile = new File(srcPath);
            long srcFileSize = srcFile.length();
            System.out.println("源图片：" + srcPath + "，大小：" + srcFileSize / 1024
                    + "kb");

            // 1、先转换成jpg
            Thumbnails.of(srcPath).scale(1f).outputQuality(0.0f).toFile(desPath);
            // 递归压缩，直到目标文件大小小于desFileSize
            commpressPicCycle(desPath, desFileSize, accuracy);

            File desFile = new File(desPath);
            System.out.println("目标图片：" + desPath + "，大小" + desFile.length()
                    / 1024 + "kb");
            System.out.println("图片压缩完成！");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return desPath;
    }
    /**
     * 图片压缩:按指定大小把图片进行缩放（会遵循原图高宽比例）
     * 并设置图片文件大小
     */
    private static void commpressPicCycle(String desPath, long desFileSize,
                                          double accuracy) throws IOException {
        File srcFileJPG = new File(desPath);
        long srcFileSizeJPG = srcFileJPG.length();
        System.out.println("图片大小------->  "+ (srcFileSizeJPG / 1024) + " kb");
        // 2、判断大小，如果小于指定大小，不压缩；如果大于等于指定大小，压缩
        if (srcFileSizeJPG <= desFileSize * 1024) {
            return;
        }
        // 计算宽高
        BufferedImage bim = ImageIO.read(srcFileJPG);
        int srcWdith = bim.getWidth();
        int srcHeigth = bim.getHeight();
        int desWidth = new BigDecimal(srcWdith).multiply(
                new BigDecimal(accuracy)).intValue();
        int desHeight = new BigDecimal(srcHeigth).multiply(
                new BigDecimal(accuracy)).intValue();
        // 目标路径
        Thumbnails.of(desPath)
                // 目标大小
                .size(desWidth, desHeight)
                // 输出质量
                .outputQuality(accuracy)
                // 目标路径
                .toFile(desPath);

        commpressPicCycle(desPath, desFileSize, accuracy);
    }


    ////////////////////////////////////////////【按照比例进行缩放】///////////////////////////////////////////////////

    /**
     * 按照比例进行缩放
     * @param srcPath 源路径
     * @param desPath 目标路径
     * @param desFileSize 目标文件大小
     * @param accuracy 压缩精度 精度，递归压缩的比率，建议小于0.9
     * @return
     */
    public static String commpressPicForScale(String srcPath, String desPath,
                                              long desFileSize, double accuracy) {
        if (StrUtil.isEmpty(srcPath) || StrUtil.isEmpty(srcPath)) {
            return null;
        }
        if (!new File(srcPath).exists()) {
            return null;
        }
        try {
            File srcFile = new File(srcPath);
            long srcFileSize = srcFile.length();
            System.out.println("源图片：" + srcPath + "，大小：" + srcFileSize / 1024
                    + "kb");

            // 1、先转换成jpg
            Thumbnails.of(srcPath).scale(1f).toFile(desPath);
            //按照比例进行缩放
            imgScale(desPath, desFileSize, accuracy);

            File desFile = new File(desPath);
            System.out.println("目标图片：" + desPath + "，大小" + desFile.length()
                    / 1024 + "kb");
            System.out.println("图片压缩完成！");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return desPath;
    }
    /**
     * 按照比例进行缩放
     *
     */
    private static void imgScale(String desPath, long desFileSize,
                                 double accuracy) throws IOException{
        File file=new File(desPath);
        long fileSize=file.length();
        //判断大小，如果小于指定大小，不压缩；如果大于等于指定大小，压缩
        if(fileSize<=desFileSize*1024){
            return;
        }
        //按照比例进行缩小
        Thumbnails.of(desPath).scale(accuracy).toFile(desPath);//按比例缩小
        System.out.println("按照比例进行缩放");
        imgScale(desPath, desFileSize, accuracy);
    }


    ///////////////////////////////////////////【图片尺寸不变，大小改变】//////////////////////////////////////////////////////

    /**
     *  图片尺寸不变，大小改变
     * @param srcPath 源路径
     * @param desPath 目标路径
     * @param desFileSize 目标文件大小
     * @param accuracy 精度
     * @return
     */
    public static String commpressPicForScaleSize(String srcPath, String desPath,
                                                  long desFileSize, double accuracy) {
        if (StrUtil.isEmpty(srcPath) || StrUtil.isEmpty(srcPath)) {
            return null;
        }
        if (!new File(srcPath).exists()) {
            return null;
        }
        try {
            File srcFile = new File(srcPath);
            long srcFileSize = srcFile.length();
            System.out.println("源图片：" + srcPath + "，大小：" + srcFileSize / 1024 + "kb");
            // 1、先转换成jpg
            Thumbnails.of(srcPath).scale(1f).toFile(desPath);
            //按照比例进行缩放
            imgScaleSize(desPath, desFileSize, accuracy);

            File desFile = new File(desPath);
            System.out.println("目标图片：" + desPath + "，大小" + desFile.length()
                    / 1024 + "kb");
            System.out.println("图片压缩完成！");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return desPath;
    }
    /**
     * 图片尺寸不变，压缩文件大小
     */
    private static void imgScaleSize(String desPath, long desFileSize,
                                     double accuracy) throws IOException{
        File fileName=new File(desPath);
        long fileNameSize=fileName.length();
        //判断大小，如果小于指定大小，不压缩；如果大于等于指定大小，压缩
        if(fileNameSize<=desFileSize*1024){
            return;
        }
        //图片尺寸不变，压缩图片文件大小
        //图片尺寸不变，压缩图片文件大小outputQuality实现,参数1为最高质量
        Thumbnails.of(desPath).scale(1f).outputQuality(accuracy).toFile(desPath);
        System.out.println("图片尺寸不变，压缩文件大小");
        imgScaleSize(desPath, desFileSize, accuracy);
    }


}
